﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ToolKit.Mvvm.Interfaces;

namespace ToolKit.Mvvm.Extensions
{
    public static class ContainerExtension
    {
        /// <summary>
        /// 实例化所有模块，并运行模块中的RegisterType方法成员，在RegisterType方法中会注册当前模块的所有类型
        /// </summary>
        /// <param name="container"></param>
        /// <returns></returns>
        public static IContainer InitializeModule(this IContainer container)
        {
            //注册先后顺序，先处理手动注册需求，后处理自动注册需求(即标注为DependenceInjectionAttribute特性的类型注册)

            //step1 加载所有模块
            container.ModuleManager.InitializeModule();

            //step2 实例化所有模块，并运行模块中的RegisterType方法成员
            var moduleMaps = container.ModuleManager.ModuleMaps;
            var instances = container.ModuleManager.Instances;
            foreach (var module in moduleMaps)
            {
                Type moduleType = module.Value;
                if (!instances.ContainsKey(moduleType.FullName))
                {
                    object instance = Activator.CreateInstance(moduleType);
                    instances.TryAdd(moduleType.FullName, instance);
                    var methodInfo = instance.GetType().GetMethod("RegisterType");
                    methodInfo?.Invoke(instance, new object[] { container });//实现手动注册模块中的类型
                }
            }

            //step3 自动注册子模块所在程序集标注为DependenceInjectionAttribute特性的类型
            foreach (Type moduleType in moduleMaps.Values)
            {
                //获取模块所在的程序集
                Assembly assembly = moduleType.Assembly;

                //获取所有被标识依赖注入特性的Type
                List<Type> types = assembly.GetDependenceInjectionTypes();

                //注册这些依赖特性的类型
                container.Register(types);
            }

            return container;
        }
    }
}
